#include "FreeflyCamera.h"
#include <SDL/SDL_opengl.h>
#include <GL/glu.h>

FreeflyCamera::FreeflyCamera(Vector3 position, Vector3 lookAt, Vector3 vertical)
: position(position), lookAt(lookAt), vertical(vertical)
{

}

FreeflyCamera::~FreeflyCamera()
{

}

void FreeflyCamera::SetView()
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
	gluLookAt(position.GetX(),position.GetY(),position.GetZ(),
			lookAt.GetX(), lookAt.GetY(), lookAt.GetZ(),
			vertical.GetX(), vertical.GetY(), vertical.GetZ());
}


void FreeflyCamera::OnKeyboard(const SDL_KeyboardEvent & event)
{
	Vector3 front = (lookAt - position).Normalize(0.1);
	Vector3 left = (vertical^front).Normalize(0.1);
	// TODO : azerty / qwerty portability improvment ?
	switch (event.keysym.unicode)
	{
		case 'z':
			position = position + front;
			lookAt = lookAt + front;
			break;

		case 's':
			position = position - front;
			lookAt = lookAt - front;
			break;

		case 'q':
			position = position + left;
			lookAt = lookAt + left;
			break;

		case 'd':
			position = position - left;
			lookAt = lookAt - left;
			break;

		default:
			break;
	}
}


void FreeflyCamera::OnMouseMotion(const SDL_MouseMotionEvent& event)
{
	// It does not work. SDL events are crappy. Need to work with flags which are changed on events.

	// TODO : spheric coordinates gesture, not vectors
	// TODO work on xrel & yrel
	int xrel = 0;//event.xrel;
	int yrel = 0;//event.yrel;
	SDL_GetRelativeMouseState(&xrel, &yrel);

	Vector3 lookingVector = lookAt - position;
	Vector3 left = (vertical^lookingVector).Normalize(1);

	GLdouble rotationMatrix[16];
	glPushMatrix();
	glLoadIdentity();
	glRotated(xrel/10, vertical.GetX(), vertical.GetY(), vertical.GetZ());
	glRotated(-yrel/10, left.GetX(), left.GetY(), left.GetZ());
	glGetDoublev(GL_MODELVIEW_MATRIX, rotationMatrix);
	glPopMatrix();

	lookingVector = Vector3(lookingVector.GetX()*rotationMatrix[0] + lookingVector.GetY()*rotationMatrix[1] + lookingVector.GetZ()*rotationMatrix[2],
		lookingVector.GetX()*rotationMatrix[4] + lookingVector.GetY()*rotationMatrix[5] + lookingVector.GetZ()*rotationMatrix[6],
		lookingVector.GetX()*rotationMatrix[8] + lookingVector.GetY()*rotationMatrix[9] + lookingVector.GetZ()*rotationMatrix[10]);

	lookAt = position + lookingVector;
}

